import heapq
from copy import deepcopy
from typing import Tuple, Optional

from model.action import Action
from model.delay import Delay


class NetworkEvolutionCondition:
    def __init__(self) -> None:
        self._pq = []

    def __str__(self) -> str:
        if not self._pq: return "Evolution Condition: None"
        else:
            pq = deepcopy(self._pq)
            s = "Evolution Condition: \n"
            while pq:
                evolution_condition = heapq.heappop(pq)
                s += "Time: " + str(evolution_condition[0]) + " | Action: " + str(evolution_condition[1]) + "\n"
            return s

    def empty(self) -> bool:
        return not self._pq

    def put_ec(self, evolution_condition:Tuple[float, Action]):
        heapq.heappush(self._pq, evolution_condition)

    def get_ec(self) -> Optional[Tuple[float, Action]]:
        if not self._pq: return None
        else:
            return heapq.heappop(self._pq)

    def del_ec(self, time: float, action_name:str, entity_name:str):
        for i in self._pq:
            if i[1].act_name == action_name and i[1].entity == entity_name and i[0] == time:
                self._pq.remove(i)


if __name__ == "__main__":
    ec = NetworkEvolutionCondition()
    print(ec.get_ec())
    delay = Delay("certain", 2.0)
    ec.put_ec((delay.generate_delay(), Action("n1", "fail", "active")))
    ec.put_ec((delay.generate_delay(), Action("n1", "recover", "active")))
    ec.put_ec((delay.generate_delay(), Action("n1", "fail", "active")))
    ec.put_ec((delay.generate_delay(), Action("n1", "recover", "active")))
    ec.put_ec((delay.generate_delay(), Action("n1", "recover", "active")))
    ec.put_ec((delay.generate_delay(), Action("n1", "recover", "active")))
    delay = Delay("exp", 2.0)
    for _ in range(20):
        ec.put_ec((delay.generate_delay(), Action("n1", "recover", "active")))


    print(ec)
    """
    Evolution Condition: 
    Time: 0.3352779314871394 | Action: n1 recover active
    Time: 0.3371305653287324 | Action: n1 recover active
    Time: 0.394696121670886 | Action: n1 recover active
    Time: 0.444064909995856 | Action: n1 recover active
    Time: 0.4771929874338634 | Action: n1 recover active
    Time: 0.5318662505602493 | Action: n1 recover active
    Time: 0.5610316998727465 | Action: n1 recover active
    Time: 0.6490568272951204 | Action: n1 recover active
    Time: 0.8492278749917266 | Action: n1 recover active
    Time: 0.862471816053098 | Action: n1 recover active
    Time: 0.8879910153636538 | Action: n1 recover active
    Time: 0.9372673577380928 | Action: n1 recover active
    Time: 1.0339052945310576 | Action: n1 recover active
    Time: 1.1295702841924355 | Action: n1 recover active
    Time: 1.191205632832483 | Action: n1 recover active
    Time: 1.2921370601917328 | Action: n1 recover active
    Time: 1.3618458489224676 | Action: n1 recover active
    Time: 1.7791074972283907 | Action: n1 recover active
    Time: 1.9786856782910418 | Action: n1 recover active
    Time: 2.4500858551347395 | Action: n1 recover active
    Time: 2.5262788482679226 | Action: n1 fail active
    Time: 2.6487007107429776 | Action: n1 recover active
    Time: 3.125465803919273 | Action: n1 fail active
    Time: 5.4566441407269135 | Action: n1 recover active
    Time: 5.845632337055296 | Action: n1 recover active
    Time: 6.979247005686504 | Action: n1 recover active
    """
    print(ec.get_ec())
    # (0.3352779314871394, < action.Action object at 0x00000203C35CD190 >)
    print(ec.get_ec())